package io.finer.erp.jeecg.stock.service.impl;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.api.client.util.Maps;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

import io.finer.erp.jeecg.bas.entity.BasMaterial;
import io.finer.erp.jeecg.bas.entity.BasMaterialCategory;
import io.finer.erp.jeecg.bas.entity.BasMeasureUnit;
import io.finer.erp.jeecg.bas.service.IBasBizPeriodService;
import io.finer.erp.jeecg.bas.service.IBasMaterialCategoryService;
import io.finer.erp.jeecg.bas.service.IBasMaterialService;
import io.finer.erp.jeecg.bas.service.IBasMeasureUnitService;
import io.finer.erp.jeecg.finance.dto.CustomerGrossDetailDTO;
import io.finer.erp.jeecg.finance.dto.CustomerGrossProfitDTO;
import io.finer.erp.jeecg.finance.dto.GrossProfitDetailDTO;
import io.finer.erp.jeecg.finance.dto.GrossProfitSummaryDTO;
import io.finer.erp.jeecg.finance.service.IFinPayableService;
import io.finer.erp.jeecg.finance.service.IFinReceivableService;
import io.finer.erp.jeecg.finance.service.IFinaPaymentService;
import io.finer.erp.jeecg.finance.service.IFinaReceiptService;
import io.finer.erp.jeecg.stock.dto.StkEntryDetailDTO;
import io.finer.erp.jeecg.stock.dto.StkPurchaseOrderDTO;
import io.finer.erp.jeecg.stock.entity.StkCheckBill;
import io.finer.erp.jeecg.stock.entity.StkCheckBillEntry;
import io.finer.erp.jeecg.stock.entity.StkIoBill;
import io.finer.erp.jeecg.stock.entity.StkIoBillEntry;
import io.finer.erp.jeecg.stock.mapper.StkIoBillEntryMapper;
import io.finer.erp.jeecg.stock.mapper.StkIoBillMapper;
import io.finer.erp.jeecg.stock.service.IStkInventoryService;
import io.finer.erp.jeecg.stock.service.IStkIoBillService;
import io.finer.erp.jeecg.stock.vo.FreightOrIoBillVo;
import io.finer.erp.jeecg.stock.vo.StkIoBillVO;

/**
 * @Description: 出入库单
 * @Author: jeecg-boot
 * @Date:   2020-03-31
 * @Version: V1.0
 */
@Service
public class StkIoBillServiceImpl extends ServiceImpl<StkIoBillMapper, StkIoBill> implements IStkIoBillService {

	@Autowired
	private StkIoBillMapper stkIoBillMapper;
	@Autowired
	private StkIoBillEntryMapper stkIoBillEntryMapper;
	@Autowired
	private IStkInventoryService stkInventoryService;
	@Autowired
	private IFinPayableService finPayableService;
	@Autowired
	private IFinReceivableService finReceivableService;
	@Autowired
	private IBasBizPeriodService basBizPeriodService;
	@Autowired
	private IBasMeasureUnitService unitService;
	@Autowired
	private IBasMaterialService materialService;
	@Autowired
	private IBasMaterialCategoryService categoryService;
	@Autowired
	private IFinaReceiptService receiptService;
	@Autowired
	private IFinaPaymentService paymentService;
	@Autowired
	private ISysBaseAPI baseApi;

	@Override
	@Transactional
	public void saveMain(StkIoBill stkIoBill, List<StkIoBillEntry> stkIoBillEntryList) {
		basBizPeriodService.validateBillDate(stkIoBill.getBillDate());
		//入库时实现物料平方计算并更新物料的长宽等
//		this.updateMaterial(stkIoBill, stkIoBillEntryList);
		stkIoBillMapper.insert(stkIoBill);
		if(stkIoBillEntryList!=null && stkIoBillEntryList.size()>0) {
			for(StkIoBillEntry entity:stkIoBillEntryList) {
				//外键设置
				entity.setMid(stkIoBill.getId());
				entity.setBillNo(stkIoBill.getBillNo());

				String supplierId = stkIoBill.getSupplierId();
				if (supplierId!=null && !supplierId.isEmpty()) {
					entity.setSupplierId(supplierId);
				}
				stkIoBillEntryMapper.insert(entity);
			}
		}
		this.materialService.changeMaterialCPCategory(stkIoBill, stkIoBillEntryList);
	}

	@Override
	@Transactional
	public void updateMain(StkIoBill stkIoBill,List<StkIoBillEntry> stkIoBillEntryList) {
		basBizPeriodService.validateBillDate(stkIoBill.getBillDate());
		stkIoBillMapper.updateById(stkIoBill);
		this.updateMaterial(stkIoBill, stkIoBillEntryList);
		//1.先删除子表数据
		stkIoBillEntryMapper.deleteByMainId(stkIoBill.getId());
		
		//2.子表数据重新插入
		if(stkIoBillEntryList!=null && stkIoBillEntryList.size()>0) {
			for(StkIoBillEntry entity:stkIoBillEntryList) {
				//外键设置
				entity.setMid(stkIoBill.getId());
				entity.setBillNo(stkIoBill.getBillNo());

				String supplierId = stkIoBill.getSupplierId();
				if (supplierId!=null && !supplierId.isEmpty()) {
					entity.setSupplierId(supplierId);
				}
				stkIoBillEntryMapper.insert(entity);
			}
		}
	}
	
	/**
	 * @Description 入库时实现物料平方计算并更新物料的长宽等
	 * @param stkIoBill
	 * @param stkIoBillEntryList
	 * Create at: 2020-10-16 11:55:14
	 * @author: duanyong
	 * Revision:
	 *    2020-10-16 11:55:14 - first revision by duanyong
	 *        
	 */
	private void updateMaterial(StkIoBill stkIoBill, List<StkIoBillEntry> stkIoBillEntryList) {
		// 如果是采购入库
		List<String> typeList = ImmutableList.of("101", "1991", "1992", "1993");// 判断
		String ioType = stkIoBill.getStockIoType();
		if (typeList.contains(ioType)) {
			List<BasMaterial> materialList = Lists.newArrayList();
			for (StkIoBillEntry entry : stkIoBillEntryList) {
				BasMaterial material = this.materialService.getById(entry.getMaterialId());
				if(null == material) {
					continue;
				}
				// 长宽
				if (null != entry.getWidth()) {
					material.setWidth(entry.getWidth());
				}
				if (null != entry.getLength()) {
					material.setLength(entry.getLength());
				}
				// 规格
				StringBuffer model = new StringBuffer("");
				if (null != material.getWidth()) {
					model.append(material.getWidth());
					model.append("*");
					if (null != material.getLength()) {
						model.append(material.getLength());
					}
				}
				material.setModel(model.toString());
				// 平方
				BigDecimal square = BigDecimal.ZERO;
				if (typeList.get(0).equals(ioType) && StringUtils.isNotBlank(entry.getUnitId())) {
					material.setUnitId(entry.getUnitId());
					BasMeasureUnit unit = this.unitService.getById(material.getUnitId());
					String unitName = unit.getName();
					if (unitName.equals("吨")) {
						BigDecimal qty = entry.getQty();
						square = this.categoryService.getSquare(qty, material.getCategoryId());
					}
				}
				BigDecimal width = material.getWidth();
				BigDecimal length = material.getLength();
				if (typeList.get(3).equals(ioType) || typeList.get(2).equals(ioType)) {
					if (null != width && null != length) {
						square = width.divide(new BigDecimal(100), 4, BigDecimal.ROUND_DOWN).multiply(length);
					}
				}
				if (typeList.get(1).equals(ioType)) {
					if (length != null && width != null) {
						square = width.divide(new BigDecimal(100), 4, BigDecimal.ROUND_DOWN)
								.multiply(length.divide(new BigDecimal(100), 4, BigDecimal.ROUND_DOWN));
						if (null != entry.getQty()) {
							square = square.multiply(entry.getQty());
						}
					}
				}
				material.setSquare(square);
				// 供应商
				if (StringUtils.isBlank(material.getSupplier())) {
					BasMaterialCategory category = this.categoryService.getById(material.getCategoryId());
					material.setSupplier(category.getSupplierId());
				}
				materialList.add(material);
				// 保存物料
				this.materialService.updateById(material);
			}
			
		}
	}

	@Override
	@Transactional
	public void delMain(String id) {
		stkIoBillEntryMapper.deleteByMainId(id);
		stkIoBillMapper.deleteById(id);
	}

	@Override
	@Transactional
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			stkIoBillEntryMapper.deleteByMainId(id.toString());
			stkIoBillMapper.deleteById(id);
		}
	}

	@Override
	public IPage<StkIoBill> selectByStockIoType(IPage<StkIoBill> page, String stockIoType) {
		return stkIoBillMapper.selectByStockIoType(page, stockIoType);
	}

	@Override
	@Transactional
	public void approve(String id) {
		StkIoBill stkIoBill = stkIoBillMapper.selectById(id);
		if (stkIoBill == null) {
			throw new JeecgBootException(String.format("【ID：%s】出入库单不存在！", id));
		}

		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		stkIoBill.setApproverId(sysUser.getUsername());
		stkIoBill.setIsApproved(1);
		stkIoBill.setEffectiveTime(new Date());
		stkIoBill.setBillProcStatus("23");
		stkIoBillMapper.updateById(stkIoBill);

		List<StkIoBillEntry> stkIoBillEntryList = stkIoBillEntryMapper.selectByMainId(stkIoBill.getId());
		//更新实时库存
		String ioType = stkIoBill.getStockIoType();
		if(!(ioType.equals("101") && 1 == stkIoBill.getIsPda())) {//如果是pda端录入的采购入库，则已经进行了库存更新，则不对其库存进行修改
			updateInventory(stkIoBill, stkIoBillEntryList);
		}
		if (stkIoBill.getHasRp() == 1) {
			if (stkIoBill.getStockIoType().startsWith("1")) {
				finPayableService.createPayable(stkIoBill, stkIoBillEntryList);
				paymentService.createPayable(stkIoBill, stkIoBillEntryList);
			}
			else {
				finReceivableService.createReceivable(stkIoBill, stkIoBillEntryList);
//				receiptService.createReceivables(stkIoBill, stkIoBillEntryList);
			}
		}
	}

	@Override
	public boolean isApproved(Integer year, Integer month) {
		QueryWrapper<StkIoBill> queryWrapper = new QueryWrapper<>();
		queryWrapper.apply("YEAR(bill_date) = {0} AND MONTH(bill_date) = {1}", year, month);
		queryWrapper.eq("is_closed", 0);
		queryWrapper.eq("is_voided", 0);
		queryWrapper.eq("is_approved", 0);
		return stkIoBillMapper.selectCount(queryWrapper) == 0;
	}

	@Override
	@Transactional
	public void createInBill(StkCheckBill stkCheckBill, List<StkCheckBillEntry> stkCheckBillEntryList) {
		createIoBill("102", stkCheckBill, stkCheckBillEntryList);
	}

	@Override
	@Transactional
	public void createOutBill(StkCheckBill stkCheckBill, List<StkCheckBillEntry> stkCheckBillEntryList) {
		createIoBill("202", stkCheckBill, stkCheckBillEntryList);
	}

	private void createIoBill(String stockIoType, StkCheckBill stkCheckBill, List<StkCheckBillEntry> stkCheckBillEntryList) {
		StkIoBill stkIoBill = new StkIoBill();
		stkIoBill.setStockIoType(stockIoType);
		stkIoBill.setIsAuto(1);
		stkIoBill.setIsRubric(0);
		stkIoBill.setSourceType("stk_check_bill");
		stkIoBill.setSourceId(stkCheckBill.getId());
		stkIoBill.setSourceNo(stkCheckBill.getBillNo());
		stkIoBill.setBillNo(baseApi.getNoByCode("stock_io_bill_no"));
		stkIoBill.setBillDate(stkCheckBill.getBillDate()); //注意：如果设为系统日期，有可能小于当前业务期间
		stkIoBill.setHandlerId(stkCheckBill.getCheckerId());
		stkIoBill.setHasRp(0);
		stkIoBill.setIsSameSettle(0);

		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		stkIoBill.setApproverId(sysUser.getUsername());
		stkIoBill.setIsApproved(1);
		stkIoBill.setEffectiveTime(new Date());
		stkIoBill.setBillProcStatus("23");
		stkIoBill.setIsClosed(0);
		stkIoBill.setIsVoided(0);
		basBizPeriodService.validateBillDate(stkIoBill.getBillDate());
		stkIoBillMapper.insert(stkIoBill);

		List<StkIoBillEntry> stkIoBillEntryList = new ArrayList<>();
		int entryNo = 0;
		for(StkCheckBillEntry checkEntity:stkCheckBillEntryList) {
			BigDecimal qty = checkEntity.getProfitQty(); //profitQty: 盘盈为正，盘亏为负
			if (stockIoType=="202") {
				qty = qty.multiply(new BigDecimal(-1));
			}
			if (qty.compareTo(BigDecimal.ZERO) > 0) {
				StkIoBillEntry ioEntry = new StkIoBillEntry();
				//外键设置
				ioEntry.setMid(stkIoBill.getId());
				ioEntry.setBillNo(stkIoBill.getBillNo());
				ioEntry.setEntryNo(++entryNo);
				ioEntry.setSourceType("stk_check_bill.stk_check_bill_entry");
				ioEntry.setSourceEntryId(checkEntity.getId());
				ioEntry.setSourceEntryNo(String.format("%s.%d", checkEntity.getBillNo(), checkEntity.getEntryNo()));
				ioEntry.setWarehouseId(checkEntity.getWarehouseId());
				ioEntry.setMaterialId(checkEntity.getMaterialId());
				ioEntry.setBatchNo(checkEntity.getBatchNo());
				ioEntry.setUnitId(checkEntity.getUnitId());
				ioEntry.setQty(qty);
				ioEntry.setCost(BigDecimal.ZERO);
				ioEntry.setSupplierId(checkEntity.getSupplierId());
				stkIoBillEntryMapper.insert(ioEntry);
				stkIoBillEntryList.add(ioEntry);
			}
		}
		//更新实时库存
		updateInventory(stkIoBill, stkIoBillEntryList);
	}

	public void updateInventory(StkIoBill stkIoBill, List<StkIoBillEntry> stkIoBillEntryList){
		String stockIoType = stkIoBill.getStockIoType();
		for(StkIoBillEntry entry : stkIoBillEntryList) {
			if (stockIoType.startsWith("1")){ //入库
				stkInventoryService.increase(entry);
			}
			else if (stockIoType.startsWith("2")) { //出库
				stkInventoryService.newDecrease(entry);
			} else if (stockIoType.equals("301") || stockIoType.equals("3995")) { //仓库调拨
				//先调出
				stkInventoryService.decrease(entry);
				//再调入
				entry.setWarehouseId(entry.getInWarehouseId());
				stkInventoryService.increase(entry);
			} else if (stockIoType.equals("801")) { //成本调整
				stkInventoryService.changeCost(entry);
			}
		}
	}
	
	public List<StkIoBill> pdaGetPurchaseOrder(){
		return this.baseMapper.pdaGetPurchaseOrder();
	}

	@Override
	public StkIoBill getByCode(String orderNum) {
		LambdaQueryWrapper<StkIoBill> query = new LambdaQueryWrapper<StkIoBill>();
		query.eq(StkIoBill::getBillNo, orderNum);
		return this.getOne(query);
	}

	@Override
	public List<StkIoBill> getPurchaseIoBill(String purchaseBillNo) {
		LambdaQueryWrapper<StkIoBill> query = new LambdaQueryWrapper<>();
		query.eq(StkIoBill::getStockIoType, "101");
		query.eq(StkIoBill::getSourceNo, purchaseBillNo);
		List<StkIoBill> list = this.list(query);
		return list;
	}

	@Override
	public StkIoBill getSaleOutBill(String materialCode) {
		List<StkIoBill> list = this.baseMapper.getSaleOutBill(materialCode);
		if(null != list && 0 != list.size()) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public Result<?> getSaleOutBillList(Integer num) {
		LambdaQueryWrapper<StkIoBill> query = new LambdaQueryWrapper<>();
		query.eq(StkIoBill::getStockIoType, "201");
//		query.eq(StkIoBill::getBillProcStatus, "23");
		query.orderByDesc(StkIoBill::getCreateTime);
		Page<StkIoBill> page = new Page<StkIoBill>(1, num);
		IPage<StkIoBill> pageList = page(page, query);
		List<StkIoBill> list = pageList.getRecords();
		return Result.ok(list);
	}

	@Override
	public StkIoBill getByMaterialId(String materialId) {
		List<StkIoBill> list = this.baseMapper.getByMaterialId(materialId);
		if(list != null && 0 != list.size()) {
			StkIoBill bill = list.get(0);
//			String sourceNo = bill.getSourceNo();
//			ZzShoporder order = shoporderService.getByCode(sourceNo);
//			bill.set
			return bill;
		}
		return null;
	}

	@Override
	public List<StkIoBill> getSaleOutBillBySourceCode(String orderCode) {
		LambdaQueryWrapper<StkIoBill> query = new LambdaQueryWrapper<>();
		query.eq(StkIoBill::getStockIoType, "201");
		query.eq(StkIoBill::getSourceNo, orderCode);
		List<StkIoBill> list = this.list(query);
		return list;
	}


	@Override
	public List<StkIoBill> getBillBySourceCode(String orderCode) {
		LambdaQueryWrapper<StkIoBill> query = new LambdaQueryWrapper<>();
		query.eq(StkIoBill::getStockIoType, "201");
		query.eq(StkIoBill::getSourceNo, orderCode);
		query.eq(StkIoBill::getIsPrint, 0);
		List<StkIoBill> list = this.list(query);
		return list;
	}

	@Override
	public List<StkIoBill> getBillBySourceId(String sourceId) {
		LambdaQueryWrapper<StkIoBill> query = new LambdaQueryWrapper<>();
		query.eq(StkIoBill::getSourceId, sourceId);
		return list(query);
	}

	@Override
	public List<FreightOrIoBillVo> getBullBySell(){
		return baseMapper.getBullBySell();
	}
	@Override
	public List<FreightOrIoBillVo> getBullByBuy(){
		return baseMapper.getBullByBuy();
	}

	@Override
	public StkIoBill getBillByBillNo(String billNo){
		return stkIoBillMapper.getBillByBillNo(billNo);
	}

	@Override
	public StkIoBill getBillByOrderNo(String orderNo){
		LambdaQueryWrapper<StkIoBill> wrapper=new LambdaQueryWrapper<>();
		wrapper.eq(StkIoBill :: getSourceNo,orderNo);
		List<StkIoBill> ioBills=stkIoBillMapper.selectList(wrapper);
		if(ioBills.size()>0){
			return ioBills.get(0);
		}
		return null;
	}

	@Override
	public List<StkIoBill> getBillByMes(List<String> mesIds, List<String> mesCodes) {
		// TODO Auto-generated method stub
		return this.stkIoBillMapper.getBillByMes(mesIds, mesCodes);
	}

	@Override
	public List<StkPurchaseOrderDTO> querylistBySupplier(StkIoBillVO stkIoBillVO) {
		// TODO Auto-generated method stub
		//根据条件查询采购统计数据
		List<StkPurchaseOrderDTO> dtoList = baseMapper.querylistBySupplier(stkIoBillVO);
		Iterator<StkPurchaseOrderDTO> it = dtoList.iterator();
		//map存放每种物料采购数据
		Map<String,StkPurchaseOrderDTO> map = Maps.newHashMap();
		while(it.hasNext()) {
			StkPurchaseOrderDTO dto = it.next();
			//筛除没有的废数据
			if(oConvertUtils.isEmpty(dto.getMaterialId())) {
				continue;
			}
			BigDecimal qty = BigDecimal.ZERO;
//			BigDecimal cost = BigDecimal.ZERO;
			BigDecimal price = BigDecimal.ZERO;
//			BigDecimal settlePrice = BigDecimal.ZERO;
			BigDecimal settleAmt = BigDecimal.ZERO;
			//根据map存放的物料，判断该物料是否已统计过，若已统计过进行运算统计
			StkPurchaseOrderDTO orderDTO = map.get(dto.getCategoryId());
			if(oConvertUtils.isEmpty(orderDTO)) {
				settleAmt = dto.getSettleAmt().setScale(4, BigDecimal.ROUND_HALF_UP);
				if(dto.getQty().compareTo(BigDecimal.ZERO)>0) {
					price = settleAmt.divide(dto.getQty(), 4, BigDecimal.ROUND_HALF_UP);
				}
				dto.setQty(dto.getQty().setScale(4, BigDecimal.ROUND_HALF_UP));
				dto.setSettleAmt(settleAmt);;
				dto.setPrice(price);
				map.put(dto.getCategoryId(), dto);
			}else {
				settleAmt = orderDTO.getSettleAmt().add(dto.getSettleAmt()).setScale(4, BigDecimal.ROUND_HALF_UP);
				orderDTO.setSettleAmt(settleAmt);;
				qty = dto.getQty().add(orderDTO.getQty());
				orderDTO.setQty(qty.setScale(4, BigDecimal.ROUND_HALF_UP));
				price = settleAmt.divide(qty, 4, BigDecimal.ROUND_HALF_UP);
				dto.setPrice(price);
				map.put(dto.getCategoryId(), orderDTO);
			}
			
		}
		List<StkPurchaseOrderDTO> list = map.values().stream().collect(Collectors.toList());
		//根据供应商排序
		if(list!=null && list.size()>0) {
			list.sort(Comparator.comparing(StkPurchaseOrderDTO::getSupplierId));
			return list;
		}
		return Lists.newArrayList();
	}

	@Override
	public List<StkEntryDetailDTO> getEntryBySupplier(StkIoBillVO stkIoBillVO) {
		// TODO Auto-generated method stub
		List<StkEntryDetailDTO> list = baseMapper.queryEntryBySupplier(stkIoBillVO);
		if(list!=null && list.size()>0) {
			list.sort(Comparator.comparing(StkEntryDetailDTO::getCategoryId));
			return list;
		}
		return Lists.newArrayList();
	}

	@Override
	public List<GrossProfitSummaryDTO> getGrossProfit(StkIoBillVO stkIoBillVO) {
		// TODO Auto-generated method stub
		BigDecimal gpSum = BigDecimal.ZERO;//毛利总金额，用于后面计算毛利率
		BigDecimal sum = BigDecimal.ZERO;//销售总金额，便于后面计算比率
		Map<String, GrossProfitSummaryDTO> map = getDTOMap(stkIoBillVO, gpSum, sum);
		gpSum = map.get("sum").getGrossProfit();
		sum = map.get("sum").getSettlePriceSum();
		if(oConvertUtils.isNotEmpty(stkIoBillVO.getCategoryId())) {
			stkIoBillVO.setCategoryId("");
			Map<String, GrossProfitSummaryDTO> maps = getDTOMap(stkIoBillVO, gpSum, sum);
			gpSum = maps.get("sum").getGrossProfit();
			sum = maps.get("sum").getSettlePriceSum();
		}
		map.remove("sum");//去除多余数据
		List<GrossProfitSummaryDTO> list = map.values().stream().collect(Collectors.toList());
		if(list!=null && list.size()>0) {
			for(GrossProfitSummaryDTO dto:list) {
				dto.setQty(dto.getQty().setScale(4,BigDecimal.ROUND_HALF_UP));
				if(dto.getSettlePriceSum()==null) {
					dto.setSettlePriceSum(BigDecimal.ZERO);
				}
				dto.setSettlePriceSum(dto.getSettlePriceSum().setScale(4,BigDecimal.ROUND_HALF_UP));
				dto.setCost(dto.getCost().setScale(4,BigDecimal.ROUND_HALF_UP));
				dto.setGrossProfit(dto.getGrossProfit().setScale(4,BigDecimal.ROUND_HALF_UP));
				if(sum.compareTo(BigDecimal.ZERO)!=0) {
					dto.setRatio(dto.getSettlePriceSum()
							.divide(sum, 4, BigDecimal.ROUND_HALF_UP)
							.multiply(new BigDecimal("100"))+"%");
				}else {
					dto.setRatio("0%");
				}
				if(sum.compareTo(BigDecimal.ZERO)!=0) {
					dto.setGrossMargin(dto.getGrossProfit()
							.divide(gpSum, 4, BigDecimal.ROUND_HALF_UP)
							.multiply(new BigDecimal("100"))+"%");
				}else {
					dto.setGrossMargin("0%");
				}
			}
			return list;
		}
		
		return Lists.newArrayList();
	}
	
	private Map<String,GrossProfitSummaryDTO> getDTOMap(StkIoBillVO stkIoBillVO,BigDecimal gpSum,BigDecimal sum){
		List<GrossProfitSummaryDTO> dtoList = stkIoBillEntryMapper.selectBillEntry(stkIoBillVO);
		Map<String, GrossProfitSummaryDTO> map = Maps.newHashMap();//group by 物料分类
		if(dtoList!=null && dtoList.size()>0) {
			for(GrossProfitSummaryDTO dto:dtoList) {
				if(oConvertUtils.isEmpty(map.get(dto.getId()))) {
					if(dto.getQty()==null) dto.setQty(BigDecimal.ZERO);//数量
					if(dto.getSettlePrice()==null) dto.setSettlePrice(BigDecimal.ZERO);//含税单价
					dto.setSettlePriceSum(dto.getSettlePrice().multiply(dto.getQty()));//含税金额
					if(dto.getCost()==null) dto.setCost(BigDecimal.ZERO);
					dto.setGrossProfit(dto.getSettlePriceSum().subtract(dto.getCost()));//毛利金额
					/*****同比,环比此处后期再做处理******/
					
					
					map.put(dto.getId(), dto);
					gpSum.add(dto.getGrossProfit());
					sum = sum.add(dto.getSettlePriceSum());
				}else {
					GrossProfitSummaryDTO to = map.get(dto.getId());
					if(dto.getQty()!=null) {
						to.setQty(to.getQty().add(dto.getQty()));
					}
//					if(dto.getSettlePrice()!=null) {
//						to.setSettlePrice(to.getSettlePrice().add(dto.getSettlePrice()));
//					}
					if(dto.getQty()!=null && dto.getSettlePrice()!=null) {
						to.setSettlePriceSum(dto.getSettlePrice().multiply(dto.getQty()).add(to.getSettlePriceSum()));
						sum = sum.add(dto.getSettlePrice().multiply(dto.getQty()));
						gpSum = gpSum.add(dto.getSettlePrice().multiply(dto.getQty()));
					}
					if(dto.getCost()==null) dto.setCost(BigDecimal.ZERO);
					gpSum = gpSum.subtract(dto.getCost());
					to.setCost(to.getCost().add(dto.getCost()));
					to.setGrossProfit(to.getSettlePriceSum().subtract(to.getCost()));
					map.put(dto.getId(), to);
					/**
					 * 此处用于重新筛选时，比率变大问题
					 */
					dto.setSettlePriceSum(sum);
					dto.setGrossProfit(gpSum);
					map.put("sum", dto);
				}
			}
		}
		return map;
	}

	@Override
	public List<GrossProfitDetailDTO> getGrossProfitDetail(StkIoBillVO stkIoBillVO) {
		// TODO Auto-generated method stub
		List<GrossProfitDetailDTO> dtoList = stkIoBillEntryMapper.selectGrossProfitDetail(stkIoBillVO);
		if(dtoList!=null && dtoList.size()>0) {
			for(GrossProfitDetailDTO dto:dtoList) {
				dto.setSettlePriceSum(dto.getSettlePrice().multiply(dto.getQty()).setScale(4,BigDecimal.ROUND_HALF_UP));//含税金额
				if(dto.getCost()==null) dto.setCost(BigDecimal.ZERO);
				dto.setGrossProfit(dto.getSettlePriceSum().subtract(dto.getCost()).setScale(4,BigDecimal.ROUND_HALF_UP));//毛利金额
				dto.setQty(dto.getQty().setScale(4,BigDecimal.ROUND_HALF_UP));
				dto.setCost(dto.getCost().setScale(4,BigDecimal.ROUND_HALF_UP));
			}
		}
		return dtoList;
	}

	@Override
	public List<CustomerGrossProfitDTO> getCustomerGrossProfit(StkIoBillVO stkIoBillVO) {
		// TODO Auto-generated method stub
		//筛选业务员可多选
		if(oConvertUtils.isNotEmpty(stkIoBillVO.getClerkId())) {
			List<String> clerkIds = Arrays.asList(stkIoBillVO.getClerkId().split(","));
			stkIoBillVO.setClerkIds(clerkIds);
		}
		List<CustomerGrossProfitDTO> dtoList = stkIoBillEntryMapper.selectCustomerGrossProfit(stkIoBillVO);
		Map<String, CustomerGrossProfitDTO> map = Maps.newHashMap();
		if(dtoList!=null && dtoList.size()>0) {
			for(CustomerGrossProfitDTO dto:dtoList) {
				if(map.get(dto.getCategoryId()+dto.getCustomerId())==null) {
					dto.setGrossProfit(dto.getSettlePriceSum().subtract(dto.getCost()));
					map.put(dto.getCategoryId()+dto.getCustomerId(), dto);
				}else {
					CustomerGrossProfitDTO to = map.get(dto.getCategoryId()+dto.getCustomerId());
					if(!StringUtils.contains(to.getClerkId(), dto.getClerkId())) {
						to.setClerkId(to.getClerkId()+","+dto.getClerkId());
					}
					to.setGrossProfit(to.getGrossProfit().add(dto.getSettlePriceSum().subtract(dto.getCost())));
					to.setQty(to.getQty().add(dto.getQty()).setScale(4, BigDecimal.ROUND_HALF_UP));
					to.setSettlePriceSum(to.getSettlePriceSum().add(dto.getSettlePriceSum()).setScale(4, BigDecimal.ROUND_HALF_UP));
					to.setCost(to.getCost().add(dto.getCost()).setScale(4, BigDecimal.ROUND_HALF_UP));
					map.put(dto.getCategoryId()+dto.getCustomerId(), to);
				}
			}
			List<CustomerGrossProfitDTO> list = map.values().stream().collect(Collectors.toList());
			list.sort(Comparator.comparing(CustomerGrossProfitDTO::getCustomerId));
			return list;
		}
		return Lists.newArrayList();
	}

	@Override
	public List<CustomerGrossDetailDTO> getCustomerGrossProfitDetail(StkIoBillVO stkIoBillVO) {
		// TODO Auto-generated method stub
		//筛选业务员可多选
		if(oConvertUtils.isNotEmpty(stkIoBillVO.getClerkId())) {
			List<String> clerkIds = Arrays.asList(stkIoBillVO.getClerkId().split(","));
			stkIoBillVO.setClerkIds(clerkIds);
		}
		List<CustomerGrossDetailDTO> dtoList = stkIoBillEntryMapper.selectCustomerGrossProfitDetail(stkIoBillVO);
		if(dtoList!=null && dtoList.size()>0) {
			for(CustomerGrossDetailDTO dto:dtoList) {
				dto.setGrossProfit(dto.getSettlePriceSum().subtract(dto.getCost()));
			}
			return dtoList;
		}
		return Lists.newArrayList();
	}

}
